//
//  basic_cal_square_matrix.c
//  linear_algebra
//
//  Created by zhangnan on 2025/3/27.
//



#include "basic_cal_square_matrix.h"
#include "basic_cal_matrix.h"
#include "squares_matrix.h"
#include "../determinant/determinant.h"
#include "../determinant/cal_determinant.h"

/**
 * 计算整数类型方阵的行列式
 * 
 * @param matrix 指向一个整数类型方阵的指针
 * @return 方阵的行列式值
 * 
 * 此函数通过检查方阵的阶数来决定计算行列式的方法。对于1阶方阵，直接返回其元素值。
 * 对于高阶方阵，创建一个行列式参数对象，并调用按行计算行列式的函数。
 */
int det_int(SQUARES_INT_MATRIX_TYPE *matrix) {
    if (matrix->order == 1) {
        return matrix->array[0];
    }
    
    DETERMINANT_INT_TYPE params = new_int_determinant(matrix->array, matrix->order);
    return cal_int_determinant_by_row(params);
}

/**
 * 计算双精度浮点数类型方阵的行列式
 * 
 * @param matrix 指向一个双精度浮点数类型方阵的指针
 * @return 方阵的行列式值
 * 
 * 此函数与整数类型方阵的行列式计算类似，但适用于双精度浮点数类型。
 * 它同样检查方阵的阶数，并根据阶数创建行列式参数对象，最后调用按行计算行列式的函数。
 */
double det_double(SQUARES_DOUBLE_MATRIX_TYPE *matrix) {
    if (matrix->order == 1) {
        return matrix->array[0];
    }
    
    DETERMINANT_DOUBLE_TYPE params = new_double_determinant(matrix->array, matrix->order);
    return cal_double_determinant_by_row(params);
}


// 计算整数类型方阵的伴随矩阵
SQUARES_INT_MATRIX_TYPE* adjugate_int(SQUARES_INT_MATRIX_TYPE *matrix) {
    // 创建一个与输入矩阵同样大小的新矩阵用于存储伴随矩阵
    SQUARES_INT_MATRIX_TYPE *adj = create_squares_int_matrix(matrix->order);
    // 遍历矩阵的每一个元素
    for (int i = 0; i < matrix->order; i++) {
        for (int j = 0; j < matrix->order; j++) {
            // 创建子矩阵，用于计算余子式
            SQUARES_INT_MATRIX_TYPE *submatrix = create_sub_squares_int_matrix(matrix, i, j);
            // 计算代数余子式
            int cofactor = (i + j) % 2 == 0 ? 1 : -1;
            adj->array[matrix->order*j+i] = cofactor * det_int(submatrix);
            // 释放子矩阵的内存
            free_squares_int_matrix(submatrix);
        }
    }
    // 返回计算得到的伴随矩阵
    return adj;
}

// 计算双精度浮点数类型方阵的伴随矩阵
SQUARES_DOUBLE_MATRIX_TYPE* adjugate_double(SQUARES_DOUBLE_MATRIX_TYPE *matrix) {
    SQUARES_DOUBLE_MATRIX_TYPE *adj = create_squares_double_matrix(matrix->order);
    for (int i = 0; i < matrix->order; i++) {
        for (int j = 0; j < matrix->order; j++) {
            SQUARES_DOUBLE_MATRIX_TYPE *submatrix = create_sub_squares_double_matrix(matrix, i, j);
            int cofactor = (i + j) % 2 == 0 ? 1 : -1;
            adj->array[matrix->order*j+i] = (double)cofactor * det_double(submatrix);
            free_squares_double_matrix(submatrix);
        }
    }
    return adj;
}

// 计算整数类型方阵的转置矩阵
SQUARES_INT_MATRIX_TYPE* transpose_squares_matrix_int(SQUARES_INT_MATRIX_TYPE *matrix) {
    SQUARES_INT_MATRIX_TYPE *transpose = create_squares_int_matrix(matrix->order);
    for (int i = 0; i < matrix->order; i++) {
        for (int j = 0; j < matrix->order; j++) {
            transpose->array[matrix->order*i+j] = matrix->array[matrix->order*j+i];
        }
    }
    return transpose;
}

// 计算双精度浮点数类型方阵的转置矩阵
SQUARES_DOUBLE_MATRIX_TYPE* transpose_squares_matrix_double(SQUARES_DOUBLE_MATRIX_TYPE *matrix) {
    SQUARES_DOUBLE_MATRIX_TYPE *transpose = create_squares_double_matrix(matrix->order);
    for (int i = 0; i < matrix->order; i++) {
        for (int j = 0; j < matrix->order; j++) {
            transpose->array[matrix->order*i+j] = matrix->array[matrix->order*j+i];
        }
    }
    return transpose;
}

// 使用伴随矩阵法计算整数类型方阵的行列式
int det_ajugate_int(SQUARES_INT_MATRIX_TYPE *matrix) {
    SQUARES_INT_MATRIX_TYPE *adj=adjugate_int(matrix);
    int result=det_int(adj);
    free_squares_int_matrix(adj);
    return result;
}

// 使用伴随矩阵法计算双精度浮点数类型方阵的行列式
double det_ajugate_double(SQUARES_DOUBLE_MATRIX_TYPE *matrix) {
    SQUARES_DOUBLE_MATRIX_TYPE *adj = adjugate_double(matrix);
    double result=det_double(adj);
    free_squares_double_matrix(adj);
    return result;
}
